home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 26
/
Mac Magazin and MacEasy Magazine CD - Issue 26.iso
/
Wissenschaft & Technik
/
Mercutio_v1.3f
/
Sample Codeƒ
/
PopupDialog.p
< prev
next >
Wrap
Text File
|
1996-08-20
|
12KB
|
385 lines
UNIT PopupDialog;
INTERFACE
USES
{$IFC UNDEFINED THINK_PASCAL}
{$SETC THINK_PASCAL=FALSE}
{$ENDC}
{$IFC THINK_PASCAL=FALSE}
Types, ToolUtils, Resources, Controls, Menus, Memory, QuickDraw, QuickDrawText, OSUtils, Events, Dialogs, Windows, Fonts,
{$ENDC}
LowMem, MercutioAPI;
CONST
Off = 0;
On = 1;
Disable = 255;
enterKey = 3;
helpKey = 5;
deleteKey = 8;
tabKey = 9;
linefeedKey = 10;
CR = 13;
periodKey = 46;
slashKey = 47;
questionmarkKey = 63;
PopupDLOG = 3001;
popup1Item = 3;
popup2Item = 7;
defaultItem = 5;
normalPopupID = 11;
smallPopupID = 12;
PROCEDURE doPopupDialog;
IMPLEMENTATION
TYPE
popupInfo = RECORD
hMenu: MenuHandle;
selectedItem: integer;
smallFont : Boolean;
END;
DialogGlobals = RECORD
menus : array [normalPopupID..smallPopupID] of popupInfo;
END;
DialogGlobalsPtr = ^DialogGlobals;
FUNCTION ItemToMenuID(item:integer):integer;
BEGIN
IF item = popup1Item THEN ItemToMenuID:= normalPopupID ELSE ItemToMenuID := smallPopupID;
END;
PROCEDURE FakeClick (VAR theDialog: DialogPtr; theButton: Integer);
{ select/deselect a button in a Dialog }
VAR
theType: Integer;
itemHandle: Handle;
iRect: Rect;
Ticks: LongInt;
BEGIN
GetDialogItem(theDialog, theButton, theType, itemHandle, iRect);
HiliteControl(ControlHandle(itemHandle), On);
Delay(8, Ticks);
HiliteControl(ControlHandle(itemHandle), Off);
END; { of proc FakeClick }
PROCEDURE DrawDefaultBtn (theDialog: DialogPtr; ItemNumber: Integer);
{ heavy black outline }
VAR
iType: Integer;
itemHdl: Handle;
ps: PenState;
iRect: Rect;
BEGIN
SetPort(theDialog); { set window to current graf port }
GetDialogItem(theDialog, ItemNumber, iType, itemHdl, iRect); { get location }
GetPenState(ps); { save current pen }
PenNormal;
PenSize(3, 3);
InsetRect(iRect, -4, -4);
FrameRoundRect(iRect, 16, 16);
SetPenState(ps); { restore old pen }
END; { of proc DrawDefaultBtn }
PROCEDURE UpdatePopUp (theDialog: DialogPtr; Item: Integer);
{ draw popup menu }
VAR
aRect: Rect;
theGlobals: DialogGlobalsPtr;
IsNovice: boolean;
theType: Integer;
itemHdl: Handle;
iRect: Rect;
menuID:integer;
BEGIN
theGlobals := DialogGlobalsPtr(GetWRefCon(theDialog));
menuID := ItemToMenuID(Item);
GetDialogItem(theDialog, Item, theType, itemHdl, aRect);
InsetRect(aRect, -2, -2);
EraseRect(aRect);
InsetRect(aRect, 2, 2);
IF theGlobals^.menus[menuID].smallFont THEN BEGIN
TextSize(9);
TextFont(geneva);
END;
MDEF_CalcItemSize(theGlobals^.menus[menuID].hMenu, theGlobals^.menus[menuID].selectedItem, aRect);
MoveTo(aRect.left + 2, aRect.bottom);
LineTo(aRect.right, aRect.bottom);
MoveTo(aRect.right, aRect.top + 2);
LineTo(aRect.right, aRect.bottom);
MoveTo(aRect.left + 6, aRect.bottom - 5); { move to text position }
FillRect(aRect, qd.white);
MDEF_DrawItem(theGlobals^.menus[menuID].hMenu, theGlobals^.menus[menuID].selectedItem, aRect);
FrameRect(aRect);
SetDialogItem(theDialog, Item, theType, itemHdl, aRect);
IF theGlobals^.menus[menuID].smallFont THEN BEGIN
TextSize(0);
TextFont(0);
END;
END;
FUNCTION PopUpSelectWithWindowFont (theMenu : MenuHandle; popPt: Point; popupItem: integer; useWFont: boolean): integer;
VAR
item: integer;
itemMark : char;
oldSysFont, oldWMgrFont, oldCWMgrFont: integer;
oldSysSize, oldWMgrSize, oldCWMgrSize: integer;
saveFontFam: integer;
curPort: GrafPtr;
wMgrPort: GrafPtr;
wMgrCPort: CGrafPtr;
theWorld:SysEnvRec;
BEGIN
oldSysFont := LMGetSysFontFam;
oldSysSize := LMGetSysFontSize;
GetPort(curPort);
IF ((curPort^.txFont = oldSysFont) & (curPort^.txSize = oldSysSize)) THEN
useWFont := false;
IF useWFont THEN BEGIN
{ hack to fix bugs caused by programs that mess up the WindowMgr port(s)
(e.g. MacWrite & Word) - thanks to Leonard Rosenthal for soln }
GetWMgrPort(wMgrPort);
SetPort(wMgrPort);
oldWMgrFont := wMgrPort^.txFont;
oldWMgrSize := wMgrPort^.txSize;
TextFont(wMgrPort^.txFont);
TextSize(wMgrPort^.txSize);
IF ((SysEnvirons (1, theWorld) = noErr) & (theWorld.hasColorQD)) THEN BEGIN
GetCWMgrPort(wMgrCPort);
SetPort(GrafPtr(wMgrCPort));
oldCWMgrFont := wMgrCPort^.txFont;
oldCWMgrSize := wMgrCPort^.txSize;
TextFont(wMgrCPort^.txFont);
TextSize(wMgrCPort^.txSize);
END
ELSE
theWorld.hasColorQD:=false;
{ end-of-hack }
SetPort(curPort);
LMSetSysFontFam(curPort^.txFont);
LMSetSysFontSize(curPort^.txSize);
LMSetLastSPExtra(longint(-1));
END;
IF (popupItem > 0) THEN BEGIN
GetItemMark(theMenu, popupItem, itemMark);
IF useWFont THEN
SetItemMark(theMenu, popupItem, '*')
ELSE
SetItemMark(theMenu, popupItem, char(checkMark));
END;
CalcMenuSize(theMenu);
item := PopUpMenuSelect(theMenu, popPt.v, popPt.h, popupItem);
IF (popupItem > 0) THEN
SetItemMark(theMenu, popupItem, itemMark);
IF useWFont THEN BEGIN
{ part 2 of hack }
SetPort(wMgrPort);
TextFont(oldWMgrFont);
TextSize(oldWMgrFont);
IF theWorld.hasColorQD THEN BEGIN
SetPort(GrafPtr(wMgrCPort));
TextFont(oldCWMgrFont);
TextSize(oldCWMgrSize);
END;
{ end-of-hack-part-2 }
SetPort(curPort);
LMSetSysFontSize(oldSysSize);
LMSetSysFontFam(oldSysFont);
LMSetLastSPExtra(longint(-1));
END;
PopUpSelectWithWindowFont := item;
END;
PROCEDURE HandleMouseDown (theDialog:DialogPtr; itemHit: integer);
VAR
theGlobals: DialogGlobalsPtr;
iType: integer;
iRect: Rect;
iHandle: Handle;
popupRect: Rect;
popupResult:integer;
menuID:integer;
BEGIN
theGlobals := DialogGlobalsPtr(GetWRefCon(theDialog));
menuID := ItemToMenuID(itemHit);
CASE itemHit OF
popup1Item, popup2Item: BEGIN
GetDialogItem(theDialog, itemHit, iType, iHandle, iRect);
SetRect(popupRect, iRect.left , iRect.top, iRect.left + theGlobals^.menus[menuID].hMenu^^.menuWidth + 4, iRect.bottom + 2);
LocalToGlobal(popupRect.topLeft);
LocalToGlobal(popupRect.botRight);
InsetRect(iRect, 1, 1);
{InvertRect(iRect);}
IF theGlobals^.menus[menuID].smallFont THEN BEGIN
TextFont(geneva);
TextSize(9);
END;
popupResult := PopUpSelectWithWindowFont(theGlobals^.menus[menuID].hMenu, popupRect.topLeft, theGlobals^.menus[menuID].selectedItem, theGlobals^.menus[menuID].smallFont);
IF theGlobals^.menus[menuID].smallFont THEN BEGIN
TextSize(0);
TextFont(0);
END;
{InvertRect(iRect);}
IF (popupResult > 0) AND (LoWord(popupResult) <> theGlobals^.menus[menuID].selectedItem) THEN BEGIN
CheckItem(theGlobals^.menus[menuID].hMenu, theGlobals^.menus[menuID].selectedItem, False);
theGlobals^.menus[menuID].selectedItem := LoWord(popupResult);
UpdatePopUp(theDialog, itemHit);
END;
END;
OTHERWISE
;
END;
END;
PROCEDURE HandleEvents (theDialog:DialogPtr);
VAR
theGlobals: DialogGlobalsPtr;
eventOccured: boolean;
theErr: longint;
ShiftUsed, CmdKeyUsed, BadKey: boolean;
itemHit: integer;
theEvent: EventRecord;
thePoint: Point;
theKey: integer;
whichWindow: WindowPtr; { Dummy,cause we have no windows}
windowLoc: integer;
matchedItem: longint;
menuNum: Integer; { Res ID of the menu Selected }
itemNum: Integer; { The item number selected }
BEGIN
theGlobals := DialogGlobalsPtr(GetWRefCon(theDialog));
REPEAT
eventOccured := GetNextEvent(everyEvent, theEvent);
IF eventOccured THEN BEGIN
IF IsDialogEvent(theEvent) THEN
IF DialogSelect(theEvent, DialogPtr(whichWindow), itemHit) THEN
HandleMouseDown(DialogPtr(whichWindow), itemHit);
CASE theEvent.what OF
keyDown, autoKey:{ any key down! }
BEGIN
theKey := BitAnd(theEvent.message, charCodeMask); { decode char }
CmdKeyUsed := (BitAnd(theEvent.modifiers, cmdKey) <> 0); { cmd key down? }
ShiftUsed := (BitAnd(theEvent.modifiers, shiftKey) <> 0); { shift key down? }
CASE theKey OF
enterKey, CR: { OK Button equivalents }
BEGIN
itemHit := ok;
FakeClick(theDialog, itemHit);
END;
OTHERWISE
IF CmdKeyUsed & (theKey = periodKey) THEN BEGIN
FakeClick(theDialog, cancel);
itemHit := cancel;
END ELSE BEGIN
matchedItem := MDEF_MenuKey(theEvent.message, theEvent.modifiers, theGlobals^.menus[normalPopupID].hMenu);
IF (matchedItem > 0) THEN BEGIN
menuNum := HiWrd(matchedItem); { get the menu number }
itemNum := LoWrd(matchedItem); { get the item number }
IF menuNum = normalPopupID THEN BEGIN
theGlobals^.menus[menuNum].selectedItem := itemNum;
UpdatePopUp(theDialog, 3);
END ELSE IF menuNum = smallPopupID THEN BEGIN
theGlobals^.menus[menuNum].selectedItem := itemNum;
UpdatePopUp(theDialog, 7);
END;
END;
END;
END;
END;
mouseDown: { we had a mouse-down theEvent }
BEGIN
windowLoc := FindWindow(theEvent.where, whichWindow); { find out where }
CASE windowLoc OF { now case on the location }
inMenuBar: BEGIN
SysBeep(1);
END;
inSysWindow:
SystemClick(theEvent, whichWindow); {It was in a desk acc }
inDrag: BEGIN
DragWindow(whichWindow, theEvent.where, GetGrayRgn^^.rgnBBox);
END;
inContent:
IF FrontWindow <> whichWindow THEN
SelectWindow(whichWindow);
OTHERWISE BEGIN
END;
END;
END;
OTHERWISE BEGIN
IF DialogSelect(theEvent, DialogPtr(whichWindow), itemHit) THEN BEGIN END;
END;
END;
END;
UNTIL itemHit IN [ok, cancel];
END;
PROCEDURE doPopupDialog;
VAR
theDialog: DialogPtr;
iType: integer;
iRect: Rect;
iHandle: Handle;
popupRect: Rect;
theGlobals: DialogGlobals;
BEGIN
theDialog := GetNewDialog(PopupDLOG, NIL, Pointer(-1));
IF theDialog = NIL THEN BEGIN
SysBeep(1);
exit(doPopupDialog);
END;
SetPort(theDialog);
SetWRefCon(theDialog, longint(@theGlobals));
theGlobals.menus[normalPopupID].hMenu := GetMenu(normalPopupID);
InsertMenu(theGlobals.menus[normalPopupID].hMenu, -1);
CalcMenuSize(theGlobals.menus[normalPopupID].hMenu);
theGlobals.menus[normalPopupID].selectedItem := 1;
theGlobals.menus[normalPopupID].smallFont := FALSE;
GetDialogItem(theDialog, popup1Item, iType, iHandle, iRect);
SetDialogItem(theDialog, popup1Item, userItem, Handle(NewUserItemProc(@UpdatePopUp)), iRect);
theGlobals.menus[smallPopupID].hMenu := GetMenu(smallPopupID);
InsertMenu(theGlobals.menus[smallPopupID].hMenu, -1);
CalcMenuSize(theGlobals.menus[smallPopupID].hMenu);
theGlobals.menus[smallPopupID].selectedItem := 1;
theGlobals.menus[smallPopupID].smallFont := TRUE;
GetDialogItem(theDialog, popup2Item, iType, iHandle, iRect);
SetDialogItem(theDialog, popup2Item, userItem, Handle(NewUserItemProc(@UpdatePopUp)), iRect);
GetDialogItem(theDialog, defaultItem, iType, iHandle, iRect);
SetDialogItem(theDialog, defaultItem, userItem, Handle(NewUserItemProc(@DrawDefaultBtn)), iRect);
ShowWindow(theDialog);
HandleEvents(theDialog);
DeleteMenu(normalPopupID);
DeleteMenu(smallPopupID);
DisposeDialog(theDialog);
END;
END.